package top.healthylife.basics.utils.utils;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @author maoxiaomeng
 */
@Slf4j
public class IpUtil extends SystemThreadLocal {

    /**
     * 获取请求IP地址
     */
    public static String getIp() {
        return get("ip");
    }

    /**
     * 是否是本地IP
     */
    final static String[] LOCALHOST_IP = {"127.0.0.1", "0:0:0:0:0:0:0:1"};
    final static String UNKNOWN = "unknown";
    final static Integer len = 15;
    final static String DOT = ",";


    /**
     * 手机端user-Agent请求头
     */
    public final static String[] MOBILE_AGENTS = {"iphone", "android", "ipad", "phone", "mobile", "wap", "netfront", "java", "opera mobi",
            "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry", "dopod",
            "nokia", "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma",
            "docomo", "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos",
            "techfaith", "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem",
            "wellcom", "bunjalloo", "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos",
            "pantech", "gionee", "portalmmm", "jig browser", "hiptop", "benq", "haier", "^lct", "320x320",
            "240x320", "176x220", "w3c ", "acs-", "alav", "alca", "amoi", "audi", "avan", "benq", "bird", "blac",
            "blaz", "brew", "cell", "cldc", "cmd-", "dang", "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs",
            "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g", "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi",
            "mot-", "moto", "mwbp", "nec-", "newt", "noki", "oper", "palm", "pana", "pant", "phil", "play", "port",
            "prox", "qwap", "sage", "sams", "sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem",
            "smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-", "tosh", "tsm-", "upg1", "upsi", "vk-v",
            "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc", "winw", "winw", "xda", "xda-",
            "Googlebot-Mobile"};

    /**
     * 获取ip地址
     *
     * @param request 字段说明
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress;

        ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
            log.info("尝试从请求头 Proxy-Client-IP 获取ip=>[{}]", ipAddress);
        }
        if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
            log.info("尝试从请求头 WL-Proxy-Client-IP 获取ip=>[{}]", ipAddress);
        }
        if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            log.info("尝试调用getRemoteAddr() 获取ip=>[{}]", ipAddress);
            if ("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    log.error("未知的host异常,UnknownHostException:{}", e.getMessage());
                }
                ipAddress = inet.getHostAddress();
                log.info("尝试根据网卡取本机配置的IP 获取ip=>[{}]", ipAddress);
            }
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        // "***.***.***.***".length()
        if (ipAddress != null && ipAddress.length() > len) {
            log.info("可能为代理ip=>[{}]", ipAddress);
            if (ipAddress.indexOf(DOT) > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(DOT));
                log.info("对于通过多个代理的情况，第一个IP为客户端真实IP, 获取ip=>[{}]", ipAddress);
            }
        }
        log.info("最终记录的IP为=>[{}]", ipAddress);
        return ipAddress;
    }


    /**
     * 根据请求头中的"User-agent"验证本次请求是否是手机端用户
     *
     * @param userAgent 请求消息标识
     * @return 是否是手机端用户
     */
    public static boolean isMobile(String userAgent) {
        //手机端不需要检查验证码
        boolean isMobile = false;
        if (ObjectUtil.isNotNull(userAgent)) {
            for (String mobileAgent : MOBILE_AGENTS) {
                if (userAgent.toLowerCase().contains(mobileAgent)
                        && userAgent.toLowerCase().indexOf("windows nt") <= 0
                        && userAgent.toLowerCase().indexOf("macintosh") <= 0) {
                    isMobile = true;
                    break;
                }
            }
        }
        return isMobile;
    }
}
